package demo;

import demo.utils.SM4;
import demo.utils.SM4Context;
import org.bouncycastle.crypto.digests.SM3Digest;
import sun.misc.BASE64Decoder;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.net.URLDecoder;
import java.security.SecureRandom;
import java.security.Security;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 离线码解码
 */
public class OfflineQRCodeDemo {
    private static String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

    public static void main(String[] args)  throws Exception{
        decodeLxm(); //离线码解密样例
        //生成客户信息签名
//        String st_id="18460368718"; //学工号
//        String school_id="10001";  //学校编号
//        String SM3Key="7fIh6MNcDm3X5v8X6aYz4wm77fIh6MNcDm3X5v8X6aYz4wm7"; //SM3密钥
//        generateCstSign(st_id+school_id+SM3Key);
    }

    /**
     * 生成客户信息签名
     */
    public static void generateCstSign(String data){
        byte[] md=new byte[32];
        byte[] bytes=data.getBytes();
        SM3Digest  sm3=new SM3Digest();
        sm3.update(bytes,0,bytes.length);
        sm3.doFinal(md,0);
        String cst_sign=byte2Hex(md);
        System.out.println("客户信息签名:"+cst_sign);
    }

    /**
     *将字节数组转换成十六进制
     */
    public static String byte2Hex(byte[] bytes){
        String str = "0123456789ABCDEF";
        char[] hexChar = str.toCharArray();
        char[] sb = new char[bytes.length * 2];
        int i = 0;
        for(int j = 0; i < bytes.length; ++i) {
            sb[j] = hexChar[(bytes[i] & 240) >>> 4];
            sb[j + 1] = hexChar[bytes[i] & 15];
            j += 2;
        }
        return new String(sb);
    }

    /**
     * 离线码解密样例
     */
    public static void decodeLxm(){
        String lxm_qrcode = "CCBXYLO4VZh0XGweoEPbh2ewMG01Zb7uTxD0mvjMAhDhhDG36TCQSkuCkK2vcJ0KLQ%2BSJs1YN%2FDe%2BbJttYHy6Gg8fjBNjcXZU05j4b%2BRTFYN4hFkKy3YX14I3DpF2u1IxDs%2FTCT48y5snbfEzkblsKY%2Fehg%3D%3D";

        //String lxm_qrcode="CCBXYLO4VZh0XGweoEPbh2ewMG01Zb7uTxD0mvjMAhDhhDG36TCQSkuCkK2vcJ0KLQ%2BSJs1YN%2FDe%2BbJttYHy6Gg8fjBNjcXZU05j4b%2BRTFYN4hFntTNmtfr2zdqqtKd%2F0dOuSRHus28Kh3BkIex1iQ2MPxQ%3D%3D";//离线码
        String secretKey="kjh4jkkoPb8Co3yJ"; //密钥
        //解密离线码
        String result=decrypyQrcode(URLDecoder.decode(lxm_qrcode),secretKey);
        System.out.println("解密后的离线码："+result);

        //获取解密后的离线码
        String[] lxm_text=result.split("@");
        String st_id=lxm_text[0];  //学工号
        String cst_sign=lxm_text[1];  //客户签名
        String jrhx_sign=lxm_text[2]; //建融慧学签名
        String timeStamp=lxm_text[3]; //时间戳
        String pay_flag=lxm_text[4]; //扣款标识
//        String pay_flag=lxm_text[6]; //扣款标识
        System.out.println("学工号:"+st_id+",客户签名："+cst_sign+",建融慧学签名:"+jrhx_sign+",时间戳："+timeStamp+",扣款标识："+pay_flag);
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(String.format("%02x", b));
        }
        return hex.toString();
    }

    /**
     * 生成SM4密钥
     */
    public static void generateSM4SecretKey() throws Exception{
        try {
            // 添加SM4提供者支持，通常需要引入第三方库，如Bouncy Castle
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

            // 初始化KeyGenerator
            KeyGenerator keyGenerator = KeyGenerator.getInstance("SM4");
            keyGenerator.init(64); // 初始化密钥的长度，SM4标准长度是128位

            // 生成密钥
            SecretKey key = keyGenerator.generateKey();
            byte[] keyBytes = key.getEncoded();

            // 打印密钥
            System.out.println("SM4 密钥: " + bytesToHex(keyBytes));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 生成SM3密钥
     * @throws Exception
     */
    public static void generateSM3SecretKey(int length) throws Exception{
        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(length);

        for (int i = 0; i < length; i++) {
            // 生成大写字母（65-90）或小写字母（97-122）
            int upperCase = random.nextInt(26) + 'A'; // 大写字母
            int lowerCase = random.nextInt(26) + 'a'; // 小写字母
            // 生成数字（0-9）
            int number = random.nextInt(10) + '0'; // 数字

            // 随机选择大小写字母或数字
            int randomChar = random.nextInt(3) == 0 ? upperCase : (random.nextInt(2) == 0 ? lowerCase : number);
            sb.append((char) randomChar);
        }

        // 截取前48位字符
        System.out.println("SM3密钥："+sb);

    }



    /**
     * 解密离线码
     * @param qrcode 离线码
     * @param secretKey 密钥
     * @return 解密后的离线码
     */
    public static String decrypyQrcode(String qrcode,String secretKey){
        String cipherText=qrcode.substring(5);
        try {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = 0;
            byte[] keyBytes = secretKey.getBytes();
            SM4 sm4 = new SM4();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, (new BASE64Decoder()).decodeBuffer(cipherText));
            return new String(decrypted, "GBK");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }
}
